package com.tsq.file.provider.service.impl;

import com.qiniu.common.QiniuException;
import com.tsq.file.api.FileInfo;
import com.tsq.file.provider.mapper.FileInfoMapper;
import com.tsq.file.provider.service.IFileInfoService;
import com.tsq.file.provider.utils.Base64Utils;
import com.tsq.file.provider.utils.Constant;
import com.tsq.file.provider.utils.FileUtil;
import com.tsq.file.provider.utils.ImageUtil;
import com.tsq.web.base.service.impl.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author dcy
 * @since 2019-09-18
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public abstract class AbstractIFileInfoService extends BaseServiceImpl<FileInfoMapper, FileInfo> implements IFileInfoService {

    private static final String FILE_SPLIT = ".";

    @Autowired
    private FileInfoMapper fileInfoMapper;

    /**
     * 上传文件
     *
     * @param file
     * @return
     * @throws Exception
     */
    @Override
    public FileInfo upload(MultipartFile file) throws Exception {
        FileInfo fileInfo = commonUpload(file);
        return fileInfo;
    }

    /**
     * 上传文件(base64)
     *
     * @param base64Image
     * @return
     * @throws Exception
     */
    @Override
    public FileInfo uploadBase64Image(String base64Image) throws Exception {
        //base64Image 转  MultipartFile
        MultipartFile file = Base64Utils.base64ToMultipart(base64Image);
        FileInfo fileInfo = commonUpload(file);
        return fileInfo;
    }

    /**
     * 上传文件公共业务处理
     * @param file
     * @return
     * @throws Exception
     */
    private FileInfo commonUpload(MultipartFile file) throws Exception {
        FileInfo fileInfo = FileUtil.getFileInfo(file);
        FileInfo oldFileInfo = fileInfoMapper.selectById(fileInfo.getId());
        if (oldFileInfo != null) {
            return oldFileInfo;
        }
        if (!fileInfo.getName().contains(FILE_SPLIT)) {
            throw new IllegalArgumentException("缺少后缀名");
        }
        //判断文件类型是否为图片
        Boolean isImage = ImageUtil.isImage(file.getOriginalFilename());
        if(isImage) {
            //缩略图字节数组
            byte[] fileByte= ImageUtil.createThumbnail(file);
            //上传图片
            uploadFile(file,fileInfo,fileByte);
        }else{
            //上传文件
            uploadFile(file,fileInfo);
        }
        // 设置文件来源
        fileInfo.setSource(fileType());
        // 将文件信息保存到数据库
        fileInfoMapper.insert(fileInfo);
        return fileInfo;
    }

    /**
     * 批量上传文件
     *
     * @param files
     * @return
     * @throws Exception
     */
    @Override
    public String uploadFileArr(MultipartFile[] files) throws Exception{
       Arrays.asList(files).stream().forEach(
                file -> {
                    try {
                        commonUpload(file);
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error("文件批量上传异常 =",e.getMessage());
                    }
                }
        );
        return Constant.SUCCESS_MSG;
    }

    /**
     * 批量上传文件
     *
     * @param base64ImageArr
     * @return
     * @throws Exception
     */
    @Override
    public String uploadBase64ImageArr(String[] base64ImageArr)throws Exception{
        Arrays.asList(base64ImageArr).stream().forEach(
                base64Image -> {
                    try {
                        uploadBase64Image(base64Image);
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error("Base64批量上传异常 =",e.getMessage());
                    }
                }
        );
        return Constant.SUCCESS_MSG;
    }

    /**
     * 删除文件
     *
     * @param id
     * @return
     * @throws Exception
     */
    @Override
    public Boolean deleteFile(String id) {
        Boolean isDelete = false;
        FileInfo fileInfo = fileInfoMapper.selectById(id);
        if (fileInfo != null) {
            fileInfoMapper.deleteById(fileInfo.getId());
            isDelete =  deleteFile(fileInfo);
        }
        return isDelete;
    }

    /**
     * 获取文件
     *
     * @param fileId
     * @return
     * @throws Exception
     */
    @Override
    public FileInfo getFileInfo(String fileId) throws QiniuException {
        FileInfo fileInfo = fileInfoMapper.selectById(fileId);
        return fileInfo;
    }

    /**
     * 下载文件
     *
     * @param
     * @return
     * @throws Exception
     */
    @Override
    public Boolean downLoad(String fileName,HttpServletResponse response) throws IOException {
        Boolean retResult = downLoadFile(fileName,response);
        return retResult;
    }

    /**
     * 文件来源
     *
     * @return
     */
    protected abstract String fileType();

    /**
     * 上传文件
     *
     * @param file
     * @param fileInfo
     * @param fileByte
     */
    protected abstract void uploadFile(MultipartFile file, FileInfo fileInfo,byte[] fileByte) throws Exception;

    /**
     * 上传文件
     *
     * @param file
     * @param

     */
    protected abstract void uploadFile(MultipartFile file, FileInfo fileInfo) throws Exception;

    /**
     * 删除文件资源
     *
     * @param fileInfo
     * @return
     */
    protected abstract Boolean deleteFile(FileInfo fileInfo);

    /**
     * 下载文件资源
     *
     * @param
     * @return
     */
    protected abstract Boolean downLoadFile(String fileName,HttpServletResponse response) throws IOException;

}
